package com.boge.methodExt;

import com.alibaba.fastjson.JSON;
import com.boge.methodExt.annotation.DoMehodExt;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
@Component
@Aspect
public class DoMehodExtPoint {


    @Pointcut("@annotation(com.boge.methodExt.annotation.DoMehodExt)")
    public void aopPoint(){

    }

    @Around("aopPoint() && @annotation(doMehodExt)")
    public Object doRouter(ProceedingJoinPoint pj, DoMehodExt doMehodExt) throws Throwable {
        // 01 获取切面方法
        Method method = getMethod(pj);

        Class aClass = getClass(pj);
        // 02 获取自定义注解的方法
        String methodExtName = doMehodExt.method();
        Method methodExt = aClass.getMethod(methodExtName, method.getParameterTypes());
        Class<?> returnType = methodExt.getReturnType();
        // 03 校验拦截方法的返回值是否为boolean类型
        if(!returnType.getName().equalsIgnoreCase("boolean")){
            throw new RuntimeException("annotation @DoMethodExt set method：" + methodExtName + " returnType is not boolean");
        }
        // 04 拦截正常，执行拦截方法
        boolean invoke = (boolean)methodExt.invoke(pj.getThis(),pj.getArgs());
        return invoke? pj.proceed(): JSON.parseObject(doMehodExt.returnJson(), method.getReturnType());
    }

    public Method getMethod(ProceedingJoinPoint pj) throws NoSuchMethodException {
        Signature signature = pj.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Class<?> aClass = pj.getTarget().getClass();
        return  aClass.getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
    }

    public Class getClass(ProceedingJoinPoint pj) throws NoSuchMethodException {
        Class<?> aClass = pj.getTarget().getClass();
        return  aClass;
    }

}

  